package com.liuqi.knet.remoting.transport.dispatcher;

import com.liuqi.knet.remoting.Channel;
import com.liuqi.knet.remoting.ChannelHandler;
import com.liuqi.knet.remoting.ClientConfig;
import com.liuqi.knet.remoting.KNetConfig;
import com.liuqi.knet.remoting.RemotingException;
import com.liuqi.knet.remoting.ServerConfig;
import com.liuqi.knet.remoting.transport.dispatcher.handler.AcceptsLoadHandler;
import com.liuqi.knet.remoting.transport.dispatcher.handler.AllChannelHandler;
import com.liuqi.knet.remoting.transport.dispatcher.handler.ClientVerifyHandler;
import com.liuqi.knet.remoting.transport.dispatcher.handler.MultiMessageHandler;
import com.liuqi.knet.remoting.transport.dispatcher.handler.ServerVerifyHandler;

/**
 * Handler 分配器
 *
 * @author liuqi
 * @date 2025/2/8 17:39
 **/
public class DispatcherHandlers {

    private final ChannelHandler handler;

    private final KNetConfig kNetConfig;

    public DispatcherHandlers(ChannelHandler handler, KNetConfig kNetConfig) {
        if (handler == null) {
            throw new NullPointerException("handler is null");
        }
        if (kNetConfig == null) {
            throw new NullPointerException("kNetConfig is null");
        }

        this.handler = handler;
        this.kNetConfig = kNetConfig;
    }

    /**
     * 包装服务端的 ChannelHandler
     *
     * @return
     */
    public ChannelHandler warpServer() {
        // 公共的 handler
        ChannelHandler handler = common(this.handler);

        if (kNetConfig.isEnableHeartbeat()) {
            // 处理心跳
            handler = new ServerVerifyHandler(handler, (ServerConfig) kNetConfig);
        }

        if (((ServerConfig) kNetConfig).getAccepts() > 0) {
            // 校验连接数是否已满
            handler = new AcceptsLoadHandler(handler, ((ServerConfig) kNetConfig).getAccepts());
        }

        return warp(handler);
    }

    /**
     * 包装客户端的 ChannelHandler
     *
     * @return
     */
    public ChannelHandler warpClient() {
        // 公共的 handler
        ChannelHandler handler = common(this.handler);

        if (kNetConfig.isEnableHeartbeat()) {
            // 处理心跳
            handler = new ClientVerifyHandler(handler, (ClientConfig) kNetConfig);
        }

        return warp(handler);
    }

    /**
     * 客户端和服务端公共的
     *
     * @param handler
     * @return
     */
    private ChannelHandler common(ChannelHandler handler) {
        // 通道事件分发器
        return new AllChannelHandler(handler, kNetConfig.getExecutor());
    }

    private ChannelHandler warp(ChannelHandler handler) {
        return new ChannelHandlerWrapper(
                // 多部分消息处理器
                new MultiMessageHandler(handler)
        );
    }

    private class ChannelHandlerWrapper implements ChannelHandler {

        protected ChannelHandler handler;

        public ChannelHandlerWrapper(ChannelHandler handler) {
            this.handler = handler;
        }

        @Override
        public void connected(Channel channel) throws RemotingException {
            handler.connected(channel);
        }

        @Override
        public void disconnected(Channel channel) throws RemotingException {
            handler.disconnected(channel);
        }

        @Override
        public void send(Channel channel, Object message) throws RemotingException {
            handler.send(channel, message);
        }

        @Override
        public void received(Channel channel, Object message) throws RemotingException {
            handler.received(channel, message);
        }

        @Override
        public void caught(Channel channel, Throwable exception) throws RemotingException {
            handler.caught(channel, exception);
        }

    }

}
